package cn.micai.base.concurrent;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @Auther: zhaoxinguo
 * @Date: 2018/7/9 15:31
 * @Description:
 */
public class Memoizer3<A, V> implements Computable<A, V> {

    private final Map<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>();
    private final Computable<A, V> c;

    public Memoizer3(Computable<A, V> c) {
        this.c = c;
    }

    @Override
    public V compute(A arg) throws InterruptedException {
        Future<V> f = cache.get(arg);

        if (f == null) {
            Callable<V> callable = new Callable<V>() {
                @Override
                public V call() throws Exception {
                    return c.compute(arg);
                }
            };

            FutureTask<V> ft = new FutureTask<>(callable);
            f = ft;
            cache.put(arg, ft);
            ft.run(); // 调用c.compute发生在这里
        }

        try {
            return f.get();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return null;
    }
}
